/**
 * 创建人:  @author huangpeng
 * 创建时间:  2024年12月29日 10:59
 * 项目名称:  lemon-blog-cloud
 * 文件名称:  ThirdTokenController
 * 文件描述:  @Description: 第三方登录接口
 * 公司名称:  xxxxxx
 * <p>
 * All rights Reserved, Designed By xxxxxx
 *
 * @Copyright: 2021-2024
 */
package com.lemon.auth.controller;

import com.lemon.auth.service.ThirdLoginService;
import com.lemon.common.core.constant.Constants;
import com.lemon.common.core.domain.Result;
import com.lemon.common.core.exception.ServiceException;
import com.lemon.common.security.service.TokenService;
import com.lemon.system.api.model.LoginUser;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.request.AuthGiteeRequest;
import me.zhyd.oauth.request.AuthQqRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

/**
 * 包名称：com.lemon.auth.controller
 * 类名称：ThirdTokenController
 * 类描述：第三方登录接口
 * 创建人：@author huangpeng
 * 创建时间：2024年12月29日 10:59
 */
@RestController
public class ThirdTokenController {

    private static final Logger log = LoggerFactory.getLogger(ThirdTokenController.class);
    @Qualifier("giteeAuthRequest")  // 指定要注入的 Bean 名称
    @Autowired
    private AuthGiteeRequest authGiteeRequest;

    @Qualifier("giteeBindRequest")  // 指定要注入的 Bean 名称
    @Autowired
    private AuthGiteeRequest bindGiteeRequest;

    @Qualifier("QqAuthRequest")  // 指定要注入的 Bean 名称
    @Autowired
    private AuthQqRequest authQqRequest;

    @Qualifier("QqBindRequest")  // 指定要注入的 Bean 名称
    @Autowired
    private AuthQqRequest bindQqRequest;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private ThirdLoginService thirdLoginService;

    @Value("${third.login.redirect-url}")
    private String thirdLoginRedirectUrl;

    @Value("${third.bind.redirect-url}")
    private String thirdBindRedirectUrl;

    /**
     * 获取Gitee登录跳转地址
     * @Title: renderGiteeAuth
     * @Description: 获取Gitee登录跳转地址
     * @return: Result<String>
     * @throws:
     * @author: huangpeng
     * @Date: 2024/12/27 17:35
     */
    @GetMapping("/gitee/login/render")
    public Result<String> renderGiteeAuth() {
        String state = AuthStateUtils.createState();
        String authorizeUrl = authGiteeRequest.authorize(state);
        return Result.success(authorizeUrl);
    }

    /**
     * 绑定Gitee跳转地址
     * @Title: renderGiteeBind
     * @Description: 绑定Gitee跳转地址
     * @param
     * @return: Result<String>
     * @throws:
     * @author: huangpeng
     * @Date: 2025/1/16 09:18
     */
    @GetMapping("/gitee/bind/render")
    public Result<String> renderGiteeBind() {
        String state = AuthStateUtils.createState();
        String authorizeUrl = bindGiteeRequest.authorize(state);
        return Result.success(authorizeUrl);
    }

    /**
     * 获取QQ登录跳转的地址
     * @Title: renderQqAuth
     * @Description: 获取QQ登录跳转的地址
     * @return: Result<String>
     * @throws:
     * @author: huangpeng
     * @Date: 2024/12/29 11:05
     */
    @GetMapping("/qq/login/render")
    public Result<String> renderQqAuth() {
        String state = AuthStateUtils.createState();
        String authorizeUrl = authQqRequest.authorize(state);
        return Result.success(authorizeUrl);
    }

    /**
     * 绑定Qq跳转地址
     * @Title: renderQqBind
     * @Description: 绑定Qq跳转地址
     * @param
     * @return: Result<String>
     * @throws:
     * @author: huangpeng
     * @Date: 2025/1/16 09:18
     */
    @GetMapping("/qq/bind/render")
    public Result<String> renderQqBind() {
        String state = AuthStateUtils.createState();
        String authorizeUrl = bindQqRequest.authorize(state);
        return Result.success(authorizeUrl);
    }


    /**
     * QQ登录回调
     * @Title: qqLogin
     * @Description: QQ登录回调
     * @param callback 回调参数
     * @return: Result<Object>
     * @throws:
     * @author: huangpeng
     * @Date: 2024/12/29 11:08
     */
    @GetMapping("/qq/login/callback")
    public void qqLogin(AuthCallback callback, HttpServletResponse servletResponse) {
        try {
            // 1. 获取 QQ 用户信息
            AuthResponse<AuthUser> response = authQqRequest.login(callback);
            AuthUser authUser = response.getData();
            if (authUser != null) {
                // 检查用户是否存在，不存在则需要注册新用户
                LoginUser userInfo = thirdLoginService.login(authUser);
                if (userInfo != null) {
                    // 获取登录token
                    LoginUser loginUser = new LoginUser();
                    Long userId = userInfo.getBaseUser().getId();
                    String userName = userInfo.getBaseUser().getUserCode();
                    loginUser.setUserid(userId);
                    loginUser.setUsername(userName);
                    loginUser.setLoginSystem(Constants.STR_ONE);
                    Map<String, Object> resultMap = tokenService.createToken(loginUser);
                    StringBuilder redirectUrl = new StringBuilder(thirdLoginRedirectUrl);
                    redirectUrl.append("?");
                    for (String key : resultMap.keySet()) {
                        redirectUrl.append(key).append("=").append(resultMap.get(key)).append("&");
                    }
                    redirectUrl.setLength(redirectUrl.length() - 1);
                    servletResponse.sendRedirect(redirectUrl.toString());
                } else {
                    servletResponse.sendRedirect(thirdLoginRedirectUrl+"?access_token=");
                }
            } else {
                log.info("通过qq登录系统失败，请联系系统管理员！");
            }
        }  catch (AuthException | IOException | ServiceException e) {
            log.info("通过qq登录系统失败，失败信息={}", e.getMessage());
        }
    }

    /**
     * 绑定qq回调接口
     * @Title: qqBind
     * @Description: 绑定qq回调接口
     * @param callback 回调参数
     * @throws:
     * @author: huangpeng
     * @Date: 2024/12/27 17:36
     */
    @GetMapping("/qq/bind/callback")
    public void qqBind(AuthCallback callback, HttpServletResponse servletResponse) {
        try {
            // 1. 获取 qq 用户信息
            AuthResponse<AuthUser> response = bindQqRequest.login(callback);
            AuthUser authUser = response.getData();
            if (authUser != null) {
                // 绑定账户
                Map<String, Object> resultMap = new HashMap<>();
                resultMap.put("thirdSource", authUser.getSource());
                resultMap.put("thirdUuid", authUser.getUuid());
                resultMap.put("thirdUname", URLEncoder.encode(authUser.getNickname(), Constants.UTF8));
                StringBuilder redirectUrl = new StringBuilder(thirdBindRedirectUrl);
                redirectUrl.append("?");
                for (String key : resultMap.keySet()) {
                    redirectUrl.append(key).append("=").append(resultMap.get(key)).append("&");
                }
                redirectUrl.setLength(redirectUrl.length() - 1);
                servletResponse.sendRedirect(redirectUrl.toString());
            } else {
                log.info("绑定qq账户失败，请联系系统管理员！");
            }
        } catch (AuthException | IOException | ServiceException e) {
            log.info("绑定qq账户失败，失败信息={}", e.getMessage());
        }
    }

    /**
     * gitee回调接口
     * @Title: giteeLogin
     * @Description: gitee回调接口
     * @param callback 回调参数
     * @param servletResponse 响应给前端
     * @throws:
     * @author: huangpeng
     * @Date: 2024/12/27 17:36
     */
    @GetMapping("/gitee/login/callback")
    public void giteeLogin(AuthCallback callback, HttpServletResponse servletResponse) {
        try {
            // 1. 获取 Gitee 用户信息
            AuthResponse<AuthUser> response = authGiteeRequest.login(callback);
            AuthUser authUser = response.getData();
            if (authUser != null) {
                // 检查用户是否存在，不存在则需要注册新用户
                LoginUser userInfo = thirdLoginService.login(authUser);
                if (userInfo != null) {
                    // 获取登录token
                    LoginUser loginUser = new LoginUser();
                    Long userId = userInfo.getBaseUser().getId();
                    String userName = userInfo.getBaseUser().getUserCode();
                    loginUser.setUserid(userId);
                    loginUser.setUsername(userName);
                    loginUser.setLoginSystem(Constants.STR_ONE);
                    Map<String, Object> resultMap = tokenService.createToken(loginUser);
                    StringBuilder redirectUrl = new StringBuilder(thirdLoginRedirectUrl);
                    redirectUrl.append("?");
                    for (String key : resultMap.keySet()) {
                        redirectUrl.append(key).append("=").append(resultMap.get(key)).append("&");
                    }
                    redirectUrl.setLength(redirectUrl.length() - 1);
                    servletResponse.sendRedirect(redirectUrl.toString());
                } else {
                    servletResponse.sendRedirect(thirdLoginRedirectUrl+"?access_token=");
                }
            } else {
                log.info("通过gitee登录系统失败，请联系系统管理员！");
            }
        } catch (AuthException | IOException | ServiceException e) {
            log.info("通过gitee登录系统失败，失败信息={}", e.getMessage());
        }
    }

    /**
     * 绑定gitee回调接口
     * @Title: giteeBind
     * @Description: 绑定gitee回调接口
     * @param callback 回调参数
     * @throws:
     * @author: huangpeng
     * @Date: 2024/12/27 17:36
     */
    @GetMapping("/gitee/bind/callback")
    public void giteeBind(AuthCallback callback, HttpServletResponse servletResponse) {
        try {
            // 1. 获取 Gitee 用户信息
            AuthResponse<AuthUser> response = bindGiteeRequest.login(callback);
            AuthUser authUser = response.getData();
            if (authUser != null) {
                // 绑定账户
                // Map<String, Object> resultMap = thirdLoginService.bind(authUser);
                Map<String, Object> resultMap = new HashMap<>();
                resultMap.put("thirdSource", authUser.getSource());
                resultMap.put("thirdUuid", authUser.getUuid());
                resultMap.put("thirdUname", authUser.getUsername());
                StringBuilder redirectUrl = new StringBuilder(thirdBindRedirectUrl);
                redirectUrl.append("?");
                for (String key : resultMap.keySet()) {
                    redirectUrl.append(key).append("=").append(resultMap.get(key)).append("&");
                }
                redirectUrl.setLength(redirectUrl.length() - 1);
                servletResponse.sendRedirect(redirectUrl.toString());
            } else {
                log.info("绑定gitee账户失败，请联系系统管理员！");
            }
        } catch (AuthException | IOException | ServiceException e) {
            log.info("绑定gitee账户失败，失败信息={}", e.getMessage());
        }
    }

}
